﻿#include "asynctcpclient.h"

#include <QDebug>
#include <QNetworkProxy>

namespace Common {

	AsyncTcpClient::AsyncTcpClient(QObject *parent)
		: QObject(parent)
		, m_tcpSocket(new QTcpSocket(this))
	{
		connect(m_tcpSocket, &QTcpSocket::readyRead, this, &AsyncTcpClient::slotSocketReadyRead);
		connect(m_tcpSocket, &QTcpSocket::stateChanged, this, &AsyncTcpClient::slotTcpSocketStateChange);
	}

	AsyncTcpClient::~AsyncTcpClient()
	{
		if (m_tcpSocket != NULL)
		{
			m_tcpSocket->close();
			delete m_tcpSocket;
			m_tcpSocket = NULL;
		}
	}

	QTcpSocket *AsyncTcpClient::getTcpSocket()
	{
		return m_tcpSocket;
	}

	bool AsyncTcpClient::connectToServer(int localPort, QString strTargetIp, int targetPort, const int retryTimes)
	{
		if (localPort < 0 || localPort > USHRT_MAX || strTargetIp.isEmpty() || targetPort < 0 || targetPort > USHRT_MAX)
		{
			return false;
		}

		m_tcpSocket->setProxy(QNetworkProxy::NoProxy);
		bool t_bind = m_tcpSocket->bind(QHostAddress::LocalHost, localPort, QTcpSocket::ReuseAddressHint);
		if (!t_bind)
		{
			return false;
		}

		int index = 0;
		bool ret = false;
		do
		{
			m_tcpSocket->connectToHost(strTargetIp, targetPort);
			ret = m_tcpSocket->waitForConnected(1000);
		} while (!ret && ++index < retryTimes);

		return ret;
	}

	bool AsyncTcpClient::connectToServer(QString strTargetIp, int targetPort, const int retryTimes)
	{
		if (strTargetIp.isEmpty() || targetPort < 0 || targetPort > USHRT_MAX)
		{
			return false;
		}

		m_tcpSocket->setProxy(QNetworkProxy::NoProxy);

		int index = 0;
		bool ret = false;
		do
		{
			m_tcpSocket->connectToHost(strTargetIp, targetPort);
			ret = m_tcpSocket->waitForConnected(1000);
		} while (!ret && ++index < retryTimes);

		return ret;
	}

	bool AsyncTcpClient::disconnectFromServer()
	{
		if (m_tcpSocket == nullptr)
		{
			return true;
		}

		m_tcpSocket->disconnectFromHost();
		if (m_tcpSocket->state() == QAbstractSocket::UnconnectedState
			|| m_tcpSocket->waitForDisconnected(1000))
		{
			return true;
		}
		return false;
	}

	bool AsyncTcpClient::isConnected()
	{
		if (m_tcpSocket == nullptr)
		{
			return false;
		}

		return m_tcpSocket->state() == QAbstractSocket::ConnectedState;
	}

	bool AsyncTcpClient::sendTcpMsg(QByteArray message)
	{
		if (!isConnected())
		{
			return false;
		}

		m_tcpSocket->readAll();
		m_tcpSocket->write(message);
		return m_tcpSocket->flush();
	}

	void AsyncTcpClient::clear()
	{
		if (m_tcpSocket != NULL)
		{
			m_tcpSocket->readAll();
		}
	}

	void AsyncTcpClient::slotSocketReadyRead()
	{
		QByteArray buffer = m_tcpSocket->readAll();
		if (buffer.size() > 0)
		{
			emit signalRecvMag(buffer);
		}
	}

	void AsyncTcpClient::slotTcpSocketStateChange(QAbstractSocket::SocketState state)
	{
		switch (state)
		{
			//[] socket 未连接
		case QAbstractSocket::UnconnectedState:
		{
			qDebug() << "QAbstractSocket::UnconnectedState";
			break;
		}
		//[]套接字正在执行主机名查找。
		case QAbstractSocket::HostLookupState:
		{
			qDebug() << "QAbstractSocket::HostLookupState";
			break;
		}
		//[]  套接字已开始建立连接。
		case QAbstractSocket::ConnectingState:
		{
			qDebug() << "QAbstractSocket::ConnectingState";
			break;
		}
		//[] 建立连接
		case QAbstractSocket::ConnectedState:
		{
			qDebug() << "QAbstractSocket::ConnectedState";
			break;
		}
		//[]  套接字绑定到一个地址和端口
		case QAbstractSocket::BoundState:
		{
			qDebug() << "QAbstractSocket::BoundState";
			break;
		}
		//[] 套接字即将关闭
		case QAbstractSocket::ClosingState:
		{
			qDebug() << "QAbstractSocket::ClosingState";
			break;
		}
		//[] 监听状态
		case QAbstractSocket::ListeningState:
		{
			qDebug() << "QAbstractSocket::ListeningState";
			break;
		}
		default:
			break;
		}
	}

}//namespace Common
